package com.shunda.ysdgj.manager.service.impl.system;

import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shunda.ysdgj.common.exception.CustomException;
import com.shunda.ysdgj.common.util.MenuUtil;
import com.shunda.ysdgj.common.util.ValidateUtil;
import com.shunda.ysdgj.manager.mapper.system.SysMenuMapper;
import com.shunda.ysdgj.manager.service.system.SysMenuService;
import com.shunda.ysdgj.manager.service.system.SysRoleMenuService;
import com.shunda.ysdgj.model.dto.base.IdsDto;
import com.shunda.ysdgj.model.entity.system.SysMenu;
import com.shunda.ysdgj.model.vo.ResultCodeEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@RequiredArgsConstructor
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService, IService<SysMenu> {

    private final SysRoleMenuService sysRoleMenuService;

    public List<SysMenu> findAll() {
        List<SysMenu> menuList = lambdaQuery().orderByAsc(SysMenu::getMenuSort).list();
        return MenuUtil.getTreeMenu(menuList);
    }

    public List<SysMenu> findAllAvailable() {
        List<SysMenu> menuList = lambdaQuery().eq(SysMenu::getMenuStatus, 1)
                .orderByAsc(SysMenu::getMenuSort).list();
        return MenuUtil.getTreeMenu(menuList);
    }

    public List<SysMenu> findByIds(List<Long> ids) {
        Set<Long> noRepeatIds = new HashSet<>(ids);
        List<SysMenu> menuList = lambdaQuery()
                .in(SysMenu::getId, noRepeatIds)
                .eq(SysMenu::getMenuStatus, 1)
                .orderByAsc(SysMenu::getMenuSort).list();
        return MenuUtil.getTreeMenu(menuList);
    }

    public boolean add(SysMenu sysMenu) {
        if (ValidateUtil.isBlank(sysMenu.getMenuName())
                || ValidateUtil.isBlank(sysMenu.getMenuPath())
                || ValidateUtil.isBlank(sysMenu.getRouteName())
                || ValidateUtil.isNotInteger(sysMenu.getMenuSort())) {
            throw new CustomException(ResultCodeEnum.PARAM_ERROR);
        }
        if (ValidateUtil.isNotLong(sysMenu.getParentId())) {
            sysMenu.setParentId(0L);
        }
        if (sysMenu.getParentId() > 0) {
            // 如果添加的是子菜单，则将其所有父菜单的半选状态改为1即处于半选状态
            modifyHalf(sysMenu);
        }
        sysMenu.setId(null);
        return save(sysMenu);
    }

    // 修改某个菜单的父菜单的半选状态
    private void modifyHalf(SysMenu sysMenu) {
        SysMenu parentMenu = getById(sysMenu.getParentId());
        if (parentMenu != null) {
            sysRoleMenuService.modifyMenuHalf(parentMenu.getId(), 1);
            modifyHalf(parentMenu);
        }
    }

    public boolean modify(SysMenu sysMenu) {
        if (ValidateUtil.isNotLong(sysMenu.getId())
                || ValidateUtil.isBlank(sysMenu.getMenuName())
                || ValidateUtil.isBlank(sysMenu.getMenuPath())
                || ValidateUtil.isBlank(sysMenu.getRouteName())
                || ValidateUtil.isNotInteger(sysMenu.getMenuSort())) {
            throw new CustomException(ResultCodeEnum.PARAM_ERROR);
        }
        return updateById(sysMenu);
    }

    @Transactional
    public boolean deleteByIds(IdsDto idsDto) {
        List<Long> ids = idsDto.getIds();
        if (ids.isEmpty()) {
            throw new CustomException(ResultCodeEnum.PARAM_ERROR);
        }
        Long count = lambdaQuery().in(SysMenu::getParentId, ids).count();
        if (count > 0) {
            throw new CustomException(ResultCodeEnum.SYSTEM_MENU_ERROR);
        }
        return removeByIds(ids);
    }

}
